package com.ikas.ai.server.module.system.controller;

import cn.hutool.core.lang.Assert;
import com.alibaba.fastjson.JSONObject;
import com.ikas.ai.anno.License;
import com.ikas.ai.consts.Consts;
import com.ikas.ai.handle.JsonResult;
import com.ikas.ai.handle.JsonResultType;
import com.ikas.ai.server.error.BadRequestException;
import com.ikas.ai.server.error.BusinessException;
import com.ikas.ai.server.module.AbstractBean;
import com.ikas.ai.server.module.system.model.LogOpsType;
import com.ikas.ai.server.module.system.model.User;
import com.ikas.ai.server.module.system.model.vo.UserVo;
import com.ikas.ai.server.module.system.service.CaptchaService;
import com.ikas.ai.server.module.system.service.UserService;
import com.ikas.ai.server.security.JwtUtil;
import com.ikas.ai.utils.PasswordUtil;
import com.ikas.ai.utils.RedisUtil;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * 系统管理-登录操作类
 *
 * @author deng.baohui
 */
@RestController
@RequestMapping("/user")
public class LoginController extends AbstractBean {

    @Autowired
    private UserService userService;
    @Autowired
    private CaptchaService captchaService;
    @Autowired
    private RedisUtil redisUtil;
    /**
     * RefreshToken过期时间
     */
    @Value("${accessTokenExpireTime}")
    private Integer accessTokenExpireTime;

    @Value("${ikas.switch}")
    private String switchOn;

    @Value("${login.captcha}")
    private String captcha;

    /**
     * 登录操作
     *
     * @param request
     * @param response
     * @param json
     * @return
     */
    @RequestMapping("/login")
    @License
    public JsonResult login(HttpServletRequest request, HttpServletResponse response, @RequestBody JSONObject json) {
        //用户名
        String userName = json.getString("p1");
        //密码
        String pwd = json.getString("p2");
        //记住密码
        boolean remPwd = json.getBoolean("p4");
        JsonResult result = new JsonResult(JsonResultType.OK);
        Assert.state(StringUtils.isNotBlank(userName), "用户名不能为空");
        //验证码id
        if (Consts.ON.equalsIgnoreCase(switchOn)) {
            String uuid = json.getString("uid");
            String capCode = json.getString("p5");
            if (!captcha.equalsIgnoreCase(capCode)) {
                //检验验证码是否正确
                captchaService.validate(uuid, capCode);
            }
        }
        //获取用户信息
        User user = userService.getUser(userName);
        Assert.notNull(user, "用户不存在");
        //账号锁定
        Assert.state(!(user.getStatus() != null && user.getStatus() == 0), "账号已被锁定,请联系管理员");
        String message;
        if (StringUtils.isNotBlank(pwd) && PasswordUtil.encrypt(pwd, user.getSalt()).equals(user.getPassword())) {
            String currentTimeMillis = String.valueOf(System.currentTimeMillis());
            String token = JwtUtil.generateJwt(userName, currentTimeMillis);
            redisUtil.saveBean(Consts.PREFIX_USER_LOGIN + user.getUserName(), user, accessTokenExpireTime);
            response.setHeader(Consts.TOKEN, token);
            result.add(Consts.TOKEN, token);
            //生产环境关掉cookie
            if (JwtUtil.cookieOn.equals(Consts.ON)) {
                Cookie cookie = new Cookie(Consts.TOKEN, token);
                cookie.setPath("/");
                response.addCookie(cookie);
            }
            // 修改登录时间
            userService.updateUserLoginTimeById(user.getId());
            message = "登录成功";
            // 记录登录日志
            this.logOperation(request, userName, LogOpsType.LOGIN, String.format("用户%s登录", userName));
        } else {
            message = "用户名或密码错误";
            // 记录登录日志
            this.logOperation(request, userName, LogOpsType.LOGIN, String.format("用户%s登录失败，原因：用户名或密码错误", userName));
            throw new BadRequestException(message);
        }
        result.setMessage(message);
        return result;
    }


    /**
     * 用户退出
     *
     * @param request
     * @param response
     * @return
     */
    @RequestMapping("/logout")
    public String logout(HttpServletRequest request, HttpServletResponse response) {
        String token = JwtUtil.getAuthzHeader(request);
        if (StringUtils.isNotBlank(token)) {
            try {
                String account = JwtUtil.getClaim(token, Consts.ACCOUNT);
                if (StringUtils.isNotBlank(account) && redisUtil.haskey(Consts.PREFIX_USER_LOGIN + account)) {
                    redisUtil.deleteKey(Consts.PREFIX_USER_LOGIN + account);
                    this.logOperation(request, account, LogOpsType.LOGOUT, String.format("用户%s登出", account));
                }
            } catch (Exception e) {
                throw new BusinessException("token不合法," + e.getMessage());
            }
        }
        JsonResult result = new JsonResult(JsonResultType.OK);
        result.setMessage("Logout success");
        return result.toJSON();
    }

    /**
     * 获取用户信息
     *
     * @return
     */
    @RequestMapping("/user_info")
    @License
    public String getUserInfo() {
        String userName = getUserName();
        if (StringUtils.isNotBlank(userName)) {
            UserVo userDto = userService.getUserVo(userName);
            userDto.setPassword(null);
            return JsonResult.ok().add(userDto).toJSON();
        }
        return JsonResult.success();
    }
}
